﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NAnt.Core;
using NAnt.Core.Attributes;
using System.IO;
using System.Xml;

namespace UofCASE.AgileProductLinerDSL.Nant.Tasks
{
    [TaskName("AspenPlatformVisualizer")]
    class AspenPlatformVisualizer : Task
    {
        [TaskAttribute("ProductLinerDir", Required = true)]
        [StringValidator(AllowEmpty = false)]
        public string ProductLinerDir { get; set; }

        protected override void ExecuteTask()
        {
            IList<String> resultFiles = collectFeatureResults();
            Log(Level.Info, "Visualizing " + resultFiles.Count() + " Platforms");
            foreach(String str in resultFiles)Log(Level.Info, "\t"+str);
            if (allExist(resultFiles))
            {

                FeatureResultSet resultSet = new FeatureResultSet();
                foreach (String file in resultFiles)
                {
                    Log(Level.Info, "Reading " + file);
                    resultSet.AddFromXml(File.ReadAllText(file));
                }
                String summaryFile = ProductLinerDir + "/results.html";
                Log(Level.Info, "Writing to " + summaryFile);
                File.WriteAllText(summaryFile, resultSet.ToString());
            }
        }

        private bool allExist(IList<string> resultFiles)
        {
            bool allexist = true;
            foreach (String file in resultFiles)
            {
                allexist = allexist && File.Exists(file);
                if (!allexist) break;
            }
            return allexist;
        }

        private IList<string> collectFeatureResults()
        {
            IList<String> results = new List<String>();
            String dir = ProductLinerDir + "/Platforms/";
            String [] platforms = Directory.GetDirectories(dir);
            foreach (String platform in platforms)
            {
                Console.WriteLine("Considering " + platform);
                if (!Path.GetFileName(platform).StartsWith("."))
                {
                    results.Add(platform + "/Results/featureResults.xml");
                    Console.WriteLine("Added " + platform);
                }
            }
            return results;
        }
    }

   

    class FeatureResultSet
    {
        Dictionary<String, IList<FeatureResult>> results = new Dictionary<string, IList<FeatureResult>>();
        HashSet<String> features = new HashSet<String>();
        
        public void AddFromXml(String xml){
            StringReader stringReader = new StringReader(xml);
            XmlTextReader reader = new XmlTextReader(stringReader);
            reader.WhitespaceHandling = WhitespaceHandling.Significant;
            reader.Read();

            String platform = reader.GetAttribute("Platform");
            List<FeatureResult> results = new List<FeatureResult>();
            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                    case (XmlNodeType.Element):
                        FeatureResult result = new FeatureResult(reader.GetAttribute("name"), Boolean.Parse(reader.GetAttribute("passed")));
                        results.Add(result);
                        features.Add(result.Feature);
                        break;
                    default: break;
                }
            }
            this.results.Add(platform, results);
        }

        public override String ToString()
        {
            StringBuilder buf = new StringBuilder();
            buf.Append("<table border=\"1\">");
            
            // platform row
            buf.Append("<tr>");
            buf.Append("<td>&#160;</td>");// feature column header
            foreach (String platform in results.Keys)
            {
                buf.Append("<td>").Append(platform).Append("</td>");
            }
            buf.Append("</tr>");


            //feature rows
            foreach (String feature in features)
            {
                buf.Append("<tr>");
                buf.Append("<td>").Append(feature).Append("</td>");
                foreach (String platform in results.Keys)
                {
                    bool found = false;
                    IList<FeatureResult> resultset = null;
                    results.TryGetValue(platform, out resultset);
                    if (resultset != null)
                    {
                        foreach (FeatureResult result in resultset)
                        {
                            if (result.Feature.Equals(feature))
                            {
                                buf.Append("<td style=\"background:");
                                if(result.Passed){
                                    buf.Append("#AAFFAA");
                                } else {
                                    buf.Append("#FFAAAA");
                                }
                                buf.Append(";\">&#160;</td>");
                                found = true;
                                break;
                            }
                        }
                    }
                    if (!found) buf.Append("<td>&#160;</td>");
                }
                buf.Append("</tr>");
            }

            buf.Append("</table>");
            return buf.ToString();
        }
    }

    class FeatureResult
    {
        public String Feature { get; set; }
        public bool Passed { get; set; }

        public FeatureResult(String feature, bool passed)
        {
            Feature = feature;
            Passed = passed;
        }
    }
}

